package com.zc.study.thread.casThread;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class CasABA {
    //ABA典型场景:小明 取款100->50(两次提交,1阻塞)
    //小明妈打款小明 50->100
    //阻塞线程提交 小明账户50;
    public static AtomicInteger num = new AtomicInteger(100);

    //解决方案
    public static AtomicStampedReference<Integer> numSoft = new AtomicStampedReference(100,1);

    public static void main(String[] args) {
        //A线程将num 100改为50
        new Thread(new Runnable() {
            @Override
            public void run() {
                int cc = 0;
                num.compareAndSet(100,50);
                Integer stamp = numSoft.getStamp();
                numSoft.compareAndSet(100,50,stamp,stamp+1);
                System.out.println(cc+"输出值"+num.get());
                System.out.println(cc+"soft输出值"+numSoft.getReference());
            }
        }).start();

        //B线程将num 100改为50
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int aa = 1;
                    Integer stamp = numSoft.getStamp();
                    Thread.sleep(5);
                    num.compareAndSet(100,50);
                    numSoft.compareAndSet(100,50,stamp,stamp+1);
                    System.out.println(aa+"输出值"+num.get());
                    System.out.println(aa+"soft输出值"+numSoft.getReference());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //C线程将num 50改为100;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    int bb = 2;
                    Thread.sleep(2);
                    Integer stamp = numSoft.getStamp();
                    num.compareAndSet(50,100);
                    numSoft.compareAndSet(50,100,stamp,stamp+1);
                    System.out.println(bb+"输出值"+num.get());
                    System.out.println(bb+"soft输出值"+numSoft.getReference());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("输出值"+num.get());
        System.out.println("soft输出值"+numSoft.getReference());
    }
}
